﻿#include "pch.h"
#include "until.h"

char m_c_program_path[1024] = { 0 };

#ifdef __DUII_LIB_HEADER__
void InitResource()
{
    // 资源类型
#ifdef _DEBUG
    CPaintManagerUI::SetResourceType(UILIB_FILE);
#else
    CPaintManagerUI::SetResourceType(UILIB_FILE);
    //CPaintManagerUI::SetResourceType(UILIB_ZIPRESOURCE);
#endif
    // 资源路径
    CDuiString strResourcePath = CPaintManagerUI::GetInstancePath();
    // 加载资源
    switch (CPaintManagerUI::GetResourceType())
    {
    case UILIB_FILE:
    {
        strResourcePath += _T("skin/");
        CPaintManagerUI::SetResourcePath(strResourcePath.GetData());
        // 加载资源管理器
        CResourceManager::GetInstance()->LoadResource(_T("res.xml"), NULL);
        break;
    }
    case UILIB_RESOURCE:
    {
        strResourcePath += _T("skin/");
        CPaintManagerUI::SetResourcePath(strResourcePath.GetData());
        // 加载资源管理器
        CResourceManager::GetInstance()->LoadResource(_T("IDR_RES"), _T("xml"));
        break;
    }
    case UILIB_ZIP:
    {
        strResourcePath += _T("ski/");
        CPaintManagerUI::SetResourcePath(strResourcePath.GetData());
        // 加密
        CPaintManagerUI::SetResourceZip(_T("duidemo_pwd.zip"), true, _T("duilib_ultimate"));
        //CPaintManagerUI::SetResourceZip(_T("duidemo.zip"), true);
        // 加载资源管理器
        CResourceManager::GetInstance()->LoadResource(_T("res.xml"), NULL);
        break;
    }
    case UILIB_ZIPRESOURCE:
    {
        strResourcePath += _T("skin/");
        CPaintManagerUI::SetResourcePath(strResourcePath.GetData());
        HRSRC hResource = ::FindResource(CPaintManagerUI::GetResourceDll(), _T("IDR_ZIPRES"), _T("ZIPRES"));
        if (hResource != NULL)
        {
            DWORD dwSize = 0;
            HGLOBAL hGlobal = ::LoadResource(CPaintManagerUI::GetResourceDll(), hResource);
            if (hGlobal != NULL)
            {
                dwSize = ::SizeofResource(CPaintManagerUI::GetResourceDll(), hResource);
                if (dwSize > 0)
                {
                    CPaintManagerUI::SetResourceZip((LPBYTE)::LockResource(hGlobal), dwSize);
                    // 加载资源管理器
                    CResourceManager::GetInstance()->LoadResource(_T("res.xml"), NULL);
                }
            }
            ::FreeResource(hResource);
        }
    }
    break;
    }
}
#endif 

#ifndef  __GENARL_DEFINE_HEADER__
#define __GENARL_DEFINE_HEADER__

bool wide_char_2_multi_char(wchar_t* buf, char* str)
{
    auto i_length = 0;
    //获取字节长度   
    i_length = WideCharToMultiByte(CP_ACP, 0, buf, -1, nullptr, 0, nullptr, nullptr);
    //将wchar_t值赋给_char    
    WideCharToMultiByte(CP_ACP, 0, buf, -1, str, i_length, nullptr, nullptr);
    return true;
}

bool  multi_byte2_wide_byte(const char* _char, wchar_t* _dest_tchar)
{
    const int iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, nullptr, 0);
    MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, _dest_tchar, iLength);
    return true;
}

void GetProgramFullPath()
{
    char exeFullPath[MAX_PATH]; // Full path
    string strPath = "";
    GetModuleFileNameA(NULL, exeFullPath, MAX_PATH);
    strPath = (string)exeFullPath;    // Get full path of the file
    int pos = strPath.find_last_of('\\', strPath.length());
    strcpy_s(m_c_program_path, sizeof(m_c_program_path), strPath.substr(0, pos).c_str());
    strcat_s(m_c_program_path, sizeof(m_c_program_path), "\\");
}

//初始化日志设置
void InitLogSetting()
{
    //设置程序运行的日子和路径
    char m_cTemp[1024] = { 0 };
    if (strlen(m_c_program_path) > 0)
    {
        strcat_s(m_cTemp, 1024, m_c_program_path);
        strcat_s(m_cTemp, 1024, "my_log.conf");
    }
    else
    {
        strcpy_s(m_cTemp, 1024, "D:/my_log.conf");
    }
    el::Configurations conf(m_cTemp);
    el::Loggers::reconfigureAllLoggers(conf);
    /// 防止Fatal级别日志中断程序  
    el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog);
    /// 选择划分级别的日志     
    el::Loggers::addFlag(el::LoggingFlag::HierarchicalLogging);
    /// 设置级别门阀值，修改参数可以控制日志输出  
    el::Loggers::setLoggingLevel(el::Level::Global);
}

wstring	  AsciiToUnicode(const string& str)
{
    // 预算-缓冲区中宽字节的长度    
    int unicodeLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0);
    // 给指向缓冲区的指针变量分配内存    
    wchar_t* pUnicode = (wchar_t*)malloc(sizeof(wchar_t) * unicodeLen);
    // 开始向缓冲区转换字节    
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, pUnicode, unicodeLen);
    wstring ret_str = pUnicode;
    free(pUnicode);
    return ret_str;
};

string UnicodeToAscii(const wstring& wstr)
{
    // 预算-缓冲区中多字节的长度    
    int ansiiLen = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
    // 给指向缓冲区的指针变量分配内存    
    char* pAssii = (char*)malloc(sizeof(char) * ansiiLen);
    // 开始向缓冲区转换字节    
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);
    string ret_str = pAssii;
    free(pAssii);
    return ret_str;
};

wstring Utf8ToUnicode(const string& str)
{
    // 预算-缓冲区中宽字节的长度    
    int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
    // 给指向缓冲区的指针变量分配内存    
    wchar_t* pUnicode = (wchar_t*)malloc(sizeof(wchar_t) * unicodeLen);
    // 开始向缓冲区转换字节    
    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, pUnicode, unicodeLen);
    wstring ret_str = pUnicode;
    free(pUnicode);
    return ret_str;
};

string UnicodeToUtf8(const wstring& wstr)
{
    // 预算-缓冲区中多字节的长度    
    int ansiiLen = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
    // 给指向缓冲区的指针变量分配内存    
    char* pAssii = (char*)malloc(sizeof(char) * ansiiLen);
    // 开始向缓冲区转换字节    
    WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);
    string ret_str = pAssii;
    free(pAssii);
    return ret_str;
};

/************************************
@ Brief:		ASSIC转UTF8
@ Author:		woniu201
@ Created:		2018/10/16
@ Return:
************************************/
string AsciiToUtf8(const string& str)
{
    return UnicodeToUtf8(AsciiToUnicode(str));
};

/************************************
@ Brief:		UTF8转ASSIC
@ Author:		woniu201
@ Created:		2018/10/16
@ Return:
************************************/
string Utf8ToAscii(const string& str)
{
    return UnicodeToAscii(Utf8ToUnicode(str));
};



const std::string& UTF8Url::HEX_2_NUM_MAP()
{
    static const std::string str("0123456789ABCDEF");
    return str;
}

const std::string& UTF8Url::ASCII_EXCEPTION()
{
    static const std::string str(R"("%<>[\]^_`{|})");
    return str;
}

unsigned char UTF8Url::NUM_2_HEX(const char h, const char l)
{
    unsigned char hh = std::find(std::begin(HEX_2_NUM_MAP()), std::end(HEX_2_NUM_MAP()), h) - std::begin(HEX_2_NUM_MAP());
    unsigned char ll = std::find(std::begin(HEX_2_NUM_MAP()), std::end(HEX_2_NUM_MAP()), l) - std::begin(HEX_2_NUM_MAP());
    return (hh << 4) + ll;
}

std::string UTF8Url::Encode(const std::string& url)
{
    std::string ret;
    for (auto it = url.begin(); it != url.end(); ++it)
    {
        if (((*it >> 7) & 1) || (std::count(std::begin(ASCII_EXCEPTION()), std::end(ASCII_EXCEPTION()), *it)))
        {
            ret.push_back('%');
            ret.push_back(HEX_2_NUM_MAP()[(*it >> 4) & 0x0F]);
            ret.push_back(HEX_2_NUM_MAP()[*it & 0x0F]);
        }
        else
        {
            ret.push_back(*it);
        }
    }
    return ret;
}

std::string UTF8Url::Decode(const std::string& url)
{
    std::string ret;
    for (auto it = url.begin(); it != url.end(); ++it)
    {
        if (*it == '%')
        {
            if (std::next(it++) == url.end())
            {
                throw std::invalid_argument("url is invalid");
            }
            ret.push_back(NUM_2_HEX(*it, *std::next(it)));
            if (std::next(it++) == url.end())
            {
                throw std::invalid_argument("url is invalid");
            }
        }
        else
        {
            ret.push_back(*it);
        }
    }
    return ret;
}

#endif // ! __GENARL_DEFINE_HEADER__